/**
 * This file is Copyright © 2008 Software Craftsmen Limited. All Rights Reserved.
 */
package com.softwarecraftsmen.orogeny.filing.absolutePathMetaData;

import com.softwarecraftsmen.orogeny.filing.absolutePathMetaData.posixIdentifiers.PosixGroupIdentifier;
import static com.softwarecraftsmen.orogeny.filing.absolutePathMetaData.posixIdentifiers.PosixGroupIdentifier.groupBestGuessBasedOnCurrentUserButIdentifierWillBeWrong;
import com.softwarecraftsmen.orogeny.filing.absolutePathMetaData.posixIdentifiers.PosixUserIdentifier;
import static com.softwarecraftsmen.orogeny.filing.absolutePathMetaData.posixIdentifiers.PosixUserIdentifier.userBestGuessBasedOnCurrentUserButIdentifierWillBeWrong;
import com.softwarecraftsmen.orogeny.filing.absolutePathMetaData.posixPermissions.PosixClassPermissions;
import com.softwarecraftsmen.orogeny.filing.absolutePathMetaData.posixPermissions.BestGuessDynamicPosixClassPermissions;
import org.jetbrains.annotations.NotNull;

import java.io.File;
import static java.lang.String.format;
import static java.util.Locale.UK;

public class BestGuessDynamicAbsolutePathMetaData implements AbsolutePathMetaData
{
	private final File file;
	private final BestGuessDynamicPosixClassPermissions ownerPosixClassPermissions;
	private final BestGuessDynamicPosixClassPermissions groupPosixClassPermissions;
	private final BestGuessDynamicPosixClassPermissions othersPosixClassPermissions;

	public BestGuessDynamicAbsolutePathMetaData(final @NotNull File file)
	{
		this.file = file;
		ownerPosixClassPermissions = new BestGuessDynamicPosixClassPermissions(this.file);
		groupPosixClassPermissions = ownerPosixClassPermissions;
		othersPosixClassPermissions = ownerPosixClassPermissions;
	}

	@NotNull
	public FixedReadOnlyAbsolutePathMetaData fix()
	{
		return new FixedReadOnlyAbsolutePathMetaData
		(
			sizeInBytes(),
			modificationTimeInMillisecondsSince1970(),
			owner(),
			ownerPosixClassPermissions.fix(),
			group(),
			groupPosixClassPermissions.fix(),
			othersPosixClassPermissions.fix()
		);
	}

	public long sizeInBytes()
	{
		if (file.isDirectory())
		{
			return 0;
		}
		guardExists();
		return file.length();
	}

	public long modificationTimeInMillisecondsSince1970()
	{
		return file.lastModified();
	}

	public void setModificationTimeInMillisecondsSince1970(final long modificationTimeInMillisecondsSince1970)
	{
		if (modificationTimeInMillisecondsSince1970 < 0)
		{
			throw new IllegalArgumentException(format(UK, "modificationTimeInMillisecondsSince1970 can not be negative. It is %1$s", modificationTimeInMillisecondsSince1970));
		}
		file.setLastModified(modificationTimeInMillisecondsSince1970);
	}

	@NotNull
	public PosixUserIdentifier owner()
	{
		return userBestGuessBasedOnCurrentUserButIdentifierWillBeWrong();
	}

	@NotNull
	public PosixClassPermissions ownerPermissions()
	{
		return ownerPosixClassPermissions;
	}

	@NotNull
	public PosixGroupIdentifier group()
	{
		return groupBestGuessBasedOnCurrentUserButIdentifierWillBeWrong();
	}

	@NotNull
	public PosixClassPermissions groupPermissions()
	{
		return groupPosixClassPermissions;
	}

	@NotNull
	public PosixClassPermissions othersPermissions()
	{
		return othersPosixClassPermissions;
	}

	private void guardExists()
	{
		if (!file.exists())
		{
			throw new IllegalStateException(format(UK, "Check that the backing file %1$s exists first!", file));
		}
	}
}